package util

import (
	"fmt"
	"io/ioutil"
	"os"
	"path/filepath"
	"strings"
	"testing"
	"time"
)

func closestRotatedFile(t time.Time, remainingFiles map[string]bool) string {
	minDiff := time.Duration(1<<63 - 1)
	var closestFile string

	for rotatedTimeStr := range remainingFiles {
		rotatedTime, err := time.Parse(time.RFC3339, rotatedTimeStr)
		if err != nil {
			continue
		}

		diff := t.Sub(rotatedTime)
		if diff >= 0 && diff < minDiff {
			minDiff = diff
			closestFile = rotatedTimeStr
		}
	}

	return closestFile
}

func TestRotateWriterMaxFiles(t *testing.T) {
	const maxFiles = 5
	const testDuration = 1 * time.Second

	// Create a temporary directory for the test files
	testDir, err := ioutil.TempDir("", "rotatetest")
	if err != nil {
		t.Fatalf("Failed to create temporary directory: %v", err)
	}
	defer os.RemoveAll(testDir)

	// Create the RotateWriter with maxFiles = 5
	filename := filepath.Join(testDir, "test.log")
	w, err := NewWriter(filename, maxFiles, DEFAULT_ROTATE_AND_DELETE_BOOL)
	if err != nil {
		t.Fatalf("Failed to create RotateWriter: %v", err)
	}
	defer w.Close()

	// Rotate the log file several times with sleep in between
	for i := 0; i < maxFiles*2; i++ {
		w.Rotate()
		time.Sleep(testDuration)
	}

	finishedTime := time.Now()

	// Check that no more than maxFiles rotated files exist
	matches, err := filepath.Glob(filename + ".*")
	if err != nil {
		t.Fatalf("Failed to list rotated files: %v", err)
	}

	if len(matches) > maxFiles {
		t.Errorf("Too many rotated files: expected %d, found %d", maxFiles, len(matches))
	}

	// Check that the oldest rotated files have been removed
	remainingFiles := make(map[string]bool)
	for _, match := range matches {
		remainingFiles[strings.TrimPrefix(match, filename+".")] = true
	}

	fmt.Println(remainingFiles)

	for i := 0; i < maxFiles*2; i++ {
		expectedTime := finishedTime.Add(-time.Duration(i) * testDuration)
		expectedFile := closestRotatedFile(expectedTime, remainingFiles)
		_, found := remainingFiles[expectedFile]

		if i < maxFiles && !found {
			t.Errorf("Expected file not found: %s", filename+"."+expectedFile)
		}
		if i >= maxFiles && found {
			t.Errorf("Unexpected file found: %s", filename+"."+expectedFile)
		}
	}
}
